/**
 * 写成类以后竟然有方便测试的妙用
 */
const Sequelize = require('sequelize');
const moment = require('moment');
const Op = Sequelize.Op;
const { removeEmpty } = require('../lib/utilx');
const db = require('../model/index');
const Equipment = db.models.Equipment;
const EquipmentAttribute = db.models.EquipmentAttribute;
const User = db.models.User;
const BrowsePrivileges = db.models.BrowsePrivileges;
const ApprovalPrivileges = db.models.ApprovalPrivileges;
const Department = db.models.Department;


class SuperUserController {

  async getEquipmentList(ctx) {
    let { limit, page, sStr, sType, sState, beforeTime, order, isAll } = ctx.request.body;
    order = order || 'ASC';  // 默认ASC

    let _Equipment = Equipment;
    if(isAll) {   // 如果是需要获取到已停用的设备
      _Equipment = Equipment.scope('includeStop');  // 超级管理员的包括已停用设备
    }

    if(sType === 'all' || sType === undefined || sType === null)
      sType = undefined;
    if(sState === 'all' || sState === undefined || sState === null)
      sState = undefined;

    let where = {
      type: sType,
      state: sState,
      createdAt: beforeTime ? { [Op.lte]: new Date(beforeTime) } : undefined,
    };
    if(sStr) {
      where = Object.assign(where, {
        [Op.or]: [
          {
            description: { [Op.like]: `%${sStr}%` },
          },
          {
            name: { [Op.like]: `%${sStr}%` },
          },
          {
            scope: { [Op.like]: `%${sStr}%` },
          },
          {
            id: { [Op.like]: `%${sStr}%` },
          }
        ]
      });
    }
    where = removeEmpty(where);

    let totalCount = await _Equipment.count({
      where,
    });
    // todo: 这里使用include子句时，如果某个设备Equipment没有EquipmentAttribute，这里findAll就不会返回这个设备！
    // todo: 不过这样正好，没有Attribute的设备自然没有什么卵用！（因为不允许修改）
    let equipmentList = await _Equipment.findAll({
      where,
      include: [{
        model: EquipmentAttribute,
      }],
      limit: limit === -1 ? undefined : limit,
      offset: limit === -1 ? undefined : limit * (page - 1),
      order: [
        ['id', order]
      ]
    });
    equipmentList = equipmentList.map(( equipment ) => {
      let values = equipment.EquipmentAttributes ?
        equipment.EquipmentAttributes.map((attribute) => {
          return attribute.dataValues.value;
        }) : [];
      return Object.assign(equipment.dataValues, {
        equipmentname: equipment.name,
        radios: equipment.radios === '正常异常' ? ['正常', '异常'] : ['无', '有'],
        hours: values,
        weekDay: values,
        state: !! equipment.state,
      });
    });

    ctx.body = {
      code: 0,
      msg: {
        count: equipmentList.length,
        totalCount,
        equipmentList,
      }
    }
  }

  async addEquipment(ctx) {
    let { equipmentname, scope, description, type, radios, weekDay, hours, label } = ctx.request.body;
    if( radios ){
      radios = radios[0] === '正常' ? '正常异常' : '无有';
    }
    hours = hours || [];
    weekDay = weekDay || [];
    let equipment = await Equipment.create({
      name: equipmentname,
      scope: scope,
      description,
      type,
      radios,
      label,
    });
    if(type === 'it' || type === 'workstation') {  // week
      for( let value of weekDay ) {
        await EquipmentAttribute.create({
          EquipmentId: equipment.id,
          value,
        });
      }
    } else {
      for( let value of hours ) {
        await EquipmentAttribute.create({
          EquipmentId: equipment.id,
          value,
        });
      }
    }
    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  async updateEquipment(ctx) {
    let { id, equipmentname, scope, description, state } = ctx.request.body;
    state = !!state;  // 类型强制转换
    console.log(state);
    await Equipment.scope('all').update({
      name: equipmentname,
      scope: scope,
      state,
      description,
    }, {
      where: {
        id,
      }
    });
    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  async deleteEquipment(ctx) {
    let { id } = ctx.request.body;
    await Equipment.scope('all').update({
      active: false,
    }, {
      where: {
        id,
      }
    });
    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  async stopEquipment(ctx) {
    let { id } = ctx.request.body;
    let equipment = await Equipment.scope('includeStop').findOne({
      where: {
        id,
      }
    });

    await Equipment.scope('includeStop').update({
      isStop: !equipment.isStop
    }, {
      where: {
        id,
      }
    });

    ctx.body = {
      code: 0,
      msg: {},
    }
  }


  async getUserList(ctx) {
    let { limit, page, sStr, sTeamName } = ctx.request.body;
    if(sTeamName === 'all')
      sTeamName = null;
    let where = {};
    if (sTeamName && sStr) {
      where = Object.assign(where, {
        [Op.and]: [{
          [Op.or]: [
            {
              username: {
                [Op.like]: `%${sStr}%`
              },
            },
            {
              phone: {
                [Op.like]: `%${sStr}%`
              }
            },
            {
              email: {
                [Op.like]: `%${sStr}%`
              }
            },
          ]
        },{
          teamName: sTeamName,
        }]
      });
    } else if(sTeamName) {
      where = Object.assign(where, {
        teamName: sTeamName,
      });
    } else if(sStr) {
      where = Object.assign(where, {
        [Op.or]: [
          {
            username: {
              [Op.like]: `%${sStr}%`
            },
          },
          {
            phone: {
              [Op.like]: `%${sStr}%`
            }
          },
          {
            email: {
              [Op.like]: `%${sStr}%`
            }
          },
        ]
      });
    }
    where = removeEmpty(where);
    let totalCount = await User.count({
      where,
    });
    let userList = await User.findAll({
      where,
      attributes: {
        exclude: ['password', 'salt']
      },
      include: [{
        model: ApprovalPrivileges,  // 如果是1:n的，即使没有审批权限也能获取到
        as : 'ApprovalPrivileges'
      }, {
        model: Department,
        as: 'Department',
        include: [{
          model: BrowsePrivileges,
        }]
      }],
      limit: limit === -1 ? undefined : limit,
      offset: limit === -1 ? undefined : limit * (page - 1),
      order: [
        ['createdAt', 'DESC']
      ]
    });
    userList = userList.map((user) => {
      return Object.assign(user.dataValues, {
        groupname: user.Department && user.Department.name,
        GroupId: user.Department && user.Department.id,
        teamname: user.teamName,
        browsePrivileges: user.Department.BrowsePrivilege,
        approvalPrivileges: user.ApprovalPrivileges,
      });
    });

    ctx.body = {
      code: 0,
      msg: {
        userList,
        totalCount,
        count: userList.length,
      }
    }
  }

  async addUser(ctx) {
    let { username, GroupId, teamname, isTeamLeader, password, phone, email, description } = ctx.request.body;
    let user = await User.findOne({
      where: {
        username,
      }
    });
    if(user) {
      ctx.body = {
        code: 5,
        msg: {
          error: '用户名已存在',
        }
      };
      return;
    }
    await User.create({
      username,
      teamName: teamname,
      isTeamLeader: !!isTeamLeader,
      password,
      phone,
      description,
      email,
      DepartmentId: GroupId,
    });

    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  async updateUser(ctx) {
    let { id, username, GroupId, teamname, isTeamLeader, password, phone, email, description } = ctx.request.body;
    let user = await User.findOne({
      where: {
        id,
      }
    });
    if(!user) {
      ctx.body = {
        code: 6,
        msg: {
          error: '用户不存在',
        }
      };
      return;
    }
    if( user.username !== username ) {
      let u = await User.findOne({
        where: {
          username,
        }
      });
      if(u) {
        ctx.body = {
          code: 5,
          msg: {
            error: '用户名已存在',
          }
        };
        return;
      }
    }

    let updateValue = {
      username,
      teamName: teamname,
      isTeamLeader: !!isTeamLeader,
      phone,
      email,
      DepartmentId: GroupId,
      password: password || undefined,
      description,
    };
    updateValue = removeEmpty(updateValue);
    await User.update(
      updateValue,
      {
        where: {
          id,
        }
      }
    );

    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  async startUser(ctx) {
    let { id } = ctx.request.body;
    let user = await User.findOne({
      where: {
        id,
      }
    });
    if(!user) {
      ctx.body = {
        code: 10,
        msg: {},
      };
      return;
    }

    await User.update({
      isStop: false,
    },{
      where: {
        id,
      }
    });
    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  async stopUser(ctx) {
    let { id } = ctx.request.body;
    let user = await User.findOne({
      where: {
        id,
      }
    });
    if(!user) {
      ctx.body = {
        code: 10,
        msg: {},
      };
      return;
    }

    await User.update({
      isStop: true,
    },{
      where: {
        id,
      }
    });
    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  async deleteUser(ctx) {
    let { id } = ctx.request.body;
    let user = await User.findOne({
      where: {
        id,
      }
    });
    if(!user) {
      ctx.body = {
        code: 10,
        msg: {},
      };
      return;
    }
    // await BrowsePrivileges.destroy({
    //   where: {
    //     id: user.BrowsePrivilegeId
    //   }
    // });
    // await ApprovalPrivileges.destroy({
    //   where: {
    //     UserId: user.id,
    //   }
    // });
    await User.update({
      active: false,
      username: `${moment().unix()}-${user.username}`,  // 更改一下用户名，防止后来的重复
    },{
      where: {
        id,
      }
    });
    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  // async setUserBrowse(ctx) {
  //   let { id, browsePrivileges } = ctx.request.body;
  //   let user = await User.findOne({
  //     where: {
  //       id,
  //     }
  //   });
  //   if(! user) {
  //     ctx.body = {
  //       code: 8,
  //       msg: {
  //         error: '用户已不存在',
  //       }
  //     };
  //     return;
  //   }
  //
  //   // 防止值被篡改
  //   delete browsePrivileges.id;
  //   delete browsePrivileges.createdAt;
  //   delete browsePrivileges.updatedAt;
  //
  //   await BrowsePrivileges.update(
  //     browsePrivileges,
  //     {
  //       where: {
  //         id,
  //       }
  //     }
  //   );
  //   ctx.body = {
  //     code: 0,
  //     msg: {},
  //   }
  // }

  async setUserApproval(ctx) {
    let { id, approvalPrivileges, } = ctx.request.body;
    console.log(approvalPrivileges);
    await ApprovalPrivileges.destroy({
      where: {
        UserId: id,
      }
    });
    for( let ap of approvalPrivileges ) {
      await ApprovalPrivileges.create({
        type: ap.type,
        step: ap.step,
        UserId: id,
      });
    }
    ctx.body = {
      code: 0,
      msg: {},
    }
  }


  async getGroupList(ctx) {
    let { page, limit } = ctx.request.body;
    let totalCount = await Department.count();
    let groupList = await Department.findAll({
      limit: limit === -1 ? undefined : limit,
      offset: limit === -1 ? undefined : ( page - 1 ) * limit,
      include: [{
        model: BrowsePrivileges,
      }]
      // include: [{  // todo: 这里如果带上include，那么没有用户的部门就不会返回 = - =
      //   model: User,
      //   attributes: ['id', 'username']
      // }]
    });
    let users = await User.findAll(
      {
        where: {
          isStop: false,
        },
      }
    );

    groupList = groupList.map((department) => {
      let teamMembers = [];
      users.forEach((user) => {
        if(user.DepartmentId === department.id) {
          teamMembers.push(user.username);
        }
      });
      return Object.assign(department.dataValues, {
        groupname: department.name,
        browsePrivileges: department.BrowsePrivilege,
        teamMembers,
      });
    });
    ctx.body = {
      code: 0,
      msg: {
        totalCount,
        count: groupList.length,
        groupList: groupList,
      }
    }
  }

  async addGroup(ctx) {
    let { groupname, description } = ctx.request.body;
    await Department.create({
      name: groupname,
      description,
    });
    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  async updateGroup(ctx) {
    let { id, groupname, description } = ctx.request.body;
    await Department.update({
      groupname,
      description,
    }, {
      where: {
        id,
      }
    });
    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  async deleteGroup(ctx) {
    let { id } = ctx.request.body;
    await Department.destroy({
      where: {
        id,
      }
    });
    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  async setGroupPrivilege(ctx) {
    let {id, browsePrivileges} = ctx.request.body;
    let department = await Department.findOne({
      where: {
        id,
      }
    });
    if (!department) {
      ctx.body = {
        code: 8,
        msg: {
          error: '部门已不存在',
        }
      };
      return;
    }

    // 防止值被篡改
    delete browsePrivileges.id;
    delete browsePrivileges.createdAt;
    delete browsePrivileges.updatedAt;

    await BrowsePrivileges.update(
      browsePrivileges,
      {
        where: {
          DepartmentId: id,
        }
      }
    );
    ctx.body = {
      code: 0,
      msg: {},
    }
  }

}

module.exports = new SuperUserController();
